package gui;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.io.Serializable;

import fn.Function;
import fn.Latex;

public class UI_Branch implements Serializable {
	private static final long serialVersionUID = -8249496728027400409L;

	private int dis;
	private Function fn;
	private Point from, to;

	public UI_Branch(UI_SFG graph, UI_Node from, UI_Node to) {
		if (from == null || to == null)
			dis = 0;
		else
			dis = getDisp(from, to, graph);
		this.from = (from == null) ? new Point(0, 0) : from.pos();
		this.to = (to == null) ? new Point(0, 0) : to.pos();
	}

	public void set(UI_SFG graph, UI_Node from, UI_Node to) {
		this.to = to.pos();
		this.from = from.pos();
		this.dis = getDisp(from, to, graph);
	}

	public UI_Branch setFn(String fn) {
		this.fn = Function.parse(fn);
		return this;
	}

	public Function fn() {
		return fn;
	}

	public Point from() {
		return from;
	}

	private int getDisp(UI_Node from, UI_Node to, UI_SFG graph) {
		if (!graph.contains(from) || !graph.contains(to))
			return 0;
		return 1;
	}

	public void paint(Graphics2D g, MyView v) {
		double x7 = 0, y7 = 0, theta = 0;
		GeneralPath p = new GeneralPath();
		p.moveTo(v.x(from.x), v.y(from.y));
		// NORMAL
		if (from.distanceTo(to) > 1) {
			theta = Math.atan2(to.y - from.y, to.x - from.x);
			double x3 = (from.x + to.x) / 2;
			double y3 = (from.y + to.y) / 2;
			double x4 = x3 + 32 * dis * Math.sin(theta);
			double y4 = y3 - 32 * dis * Math.cos(theta);
			double x5 = (x4 + from.x) / 2;
			double y5 = (y4 + from.y) / 2;
			double x6 = (x4 + to.x) / 2;
			double y6 = (y4 + to.y) / 2;
			x7 = (x5 + x6) / 2;
			y7 = (y5 + y6) / 2;
			//
			p.quadTo(x4, y4, v.x(to.x), v.y(to.y));
		}
		// SELF LOOP
		else {
			p.curveTo(from.x - 32, from.y - 32, from.x + 32, from.y - 32, from.x, from.y);
			x7 = from.x + 4;
			y7 = from.y - 24;
		}
		g.draw(p);
		Draw.triangle(g, x7, y7, theta, 0.5, 8);
		try {
			Latex.draw(fn.toLatex(), (int) x7 + 8, (int) y7 + 8, 16, null, g, g.getColor(), Color.WHITE);
		} catch (Exception e) {
			Latex.draw("?", (int) x7 + 8, (int) y7 + 8, 16, null, g, Color.RED, Color.WHITE);
		}
		g.setColor(Color.BLACK);
	}

	public Point pos() {
		double x7 = 0, y7 = 0, theta = 0;
		if (from.distanceTo(to) > 1) {
			theta = Math.atan2(to.y - from.y, to.x - from.x);
			double x3 = (from.x + to.x) / 2;
			double y3 = (from.y + to.y) / 2;
			double x4 = x3 + 32 * dis * Math.sin(theta);
			double y4 = y3 - 32 * dis * Math.cos(theta);
			double x5 = (x4 + from.x) / 2;
			double y5 = (y4 + from.y) / 2;
			double x6 = (x4 + to.x) / 2;
			double y6 = (y4 + to.y) / 2;
			x7 = (x5 + x6) / 2;
			y7 = (y5 + y6) / 2;
		}
		// SELF LOOP
		else {
			x7 = from.x + 4;
			y7 = from.y - 24;
		}
		return new Point(x7, y7);
	}

	@Override
	public String toString() {
		return fn.toLatex();
	}
}